package com.alphawavesgames.engine.rendering;

import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.CharBuffer;
import java.util.ArrayList;

/**
 *
 * @author Duncan
 * An interface to the lower level rendering Hardware
 * TODO_DRW : get the feeling this shouldn't extend SceneRenderer and
 * they should be separate classes.
 */
public class RenderHWInterface extends SceneRenderer
{
    //width and height of main frame buffer
    protected int m_frameBufferWidth;
    protected int m_frameBufferHeight;

    protected RenderContainer m_renderContainer;

    protected RenderHWInterface()
    {
        m_renderContainer = null;
    }

    public void initialise( RenderContainer renderContainer )
    {
        m_renderContainer = renderContainer;
    }

    public void create( int frameBufferWidth, int frameBufferHeight )
    {
        m_frameBufferWidth = frameBufferWidth;
        m_frameBufferHeight = frameBufferHeight;
    }

    public int getScreenWidth() { return m_frameBufferWidth; }
    public int getScreenHeight() { return m_frameBufferHeight; }



    //-----------------------------------------------------------------
    //----- API WRAPPER METHODS

    public void drawIndexedTriList( int numTris, int startIndex  )
    {

    }


    //creator method so we make the right type for the specific interface
    public IndexBuffer createIndexBuffer()
    {
        return new IndexBuffer();
    }

    public class IndexBuffer extends RenderResource
    {
        //16bit charbuffer to hold the indices
        protected CharBuffer m_indices;
        protected int m_numIndices;
        protected static final int CHAR_SIZE = 2;//2 bytes per char

        public IndexBuffer()
        {
            m_indices = null;
            m_numIndices = 0;
        }

        public void create( int numIndices, char[] data )
        {
            m_indices = ByteBuffer.allocateDirect( CHAR_SIZE * numIndices ).order( ByteOrder.nativeOrder() ).asCharBuffer();
            m_indices.put( data );
            m_numIndices = numIndices;
        }
        
    }

    //creator method so we make the right type for the specific interface
    public VertexBuffer createVertexBuffer()
    {
        return new VertexBuffer();
    }

    public class VertexBuffer extends RenderResource
    {
        //protected static RenderHWInterface sm_renderInterface = null;
        //protected static <? extends RenderHWInterface> sm_renderInterface = null;

        //only accept float element streams for now. Could think of a more generic sln
        protected ArrayList< ElementStreamFloat > m_elementStreams;

        public VertexBuffer()
        {
          //  m_elementStreams = new ArrayList< ElementStreamFloat >();
            m_elementStreams = null;
        }

//        public static void setRenderInterface( RenderHWInterface renderHWInterface )
//        {
//            sm_renderInterface = renderHWInterface;
//        }

        public void createFromElementStreams( ArrayList< ElementStreamFloat > elementStreams )
        {
            m_elementStreams = elementStreams;
        }

        /*public void addElementStream( ElementStreamFloat stream )
        {
            m_elementStreams.add( stream );
        }*/

        public ElementStreamFloat getStream( int stream )
        {
            if( ( stream < 0 ) || ( stream >= m_elementStreams.size() ) )
            {
                return null;
            }

            return m_elementStreams.get( stream );
        }

    }


    public class Texture
    {
        //todo : add the internal image representation

        protected int m_width;
        protected int m_height;
        protected int m_bitsPerTexel;
        protected boolean m_hasAlpha;
        protected boolean m_pendingLoad;


        protected Texture()
        {
            m_width = m_height = 0;
            m_bitsPerTexel = 0;
            m_hasAlpha = false;
            m_pendingLoad = false;
        }

        public void update()
        {

        }

    }
}
